[Swfed-svn] swfed-svn [371] PlaceOject, PlaceObject2 の parser 実装

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2011年 3月 1日 (火) 21:51:40 JST


Revision: 371
          http://sourceforge.jp/projects/swfed/svn/view?view=rev&revision=371
Author:   yoya
Date:     2011-03-01 21:51:40 +0900 (Tue, 01 Mar 2011)

Log Message:
-----------
PlaceOject, PlaceObject2 の parser 実装

Modified Paths:
--------------
    trunk/src/config.m4
    trunk/src/swf_tag.c

Added Paths:
-----------
    trunk/src/swf_cxform.c
    trunk/src/swf_cxform.h
    trunk/src/swf_tag_place.c
    trunk/src/swf_tag_place.h


-------------- next part --------------
Modified: trunk/src/config.m4
===================================================================
--- trunk/src/config.m4	2011-02-23 15:29:41 UTC (rev 370)
+++ trunk/src/config.m4	2011-03-01 12:51:40 UTC (rev 371)
@@ -74,5 +74,6 @@
 	swf_shape_record_edge.c swf_gradient.c  swf_gradient_record.c \
 	swf_tag_jpeg.c swf_tag_edit.c swf_tag_action.c swf_tag_lossless.c \
 	swf_tag_sound.c swf_tag_sprite.c swf_tag_shape.c y_keyvalue.c \
+	swf_tag_place.c swf_cxform.c \
 	, $ext_shared)
 fi

Added: trunk/src/swf_cxform.c
===================================================================
--- trunk/src/swf_cxform.c	                        (rev 0)
+++ trunk/src/swf_cxform.c	2011-03-01 12:51:40 UTC (rev 371)
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include "bitstream.h"
+#include "swf_cxform.h"
+
+int
+swf_cxform_parse(bitstream_t *bs, swf_cxform_t *cx) {
+    int ret, nbits;
+    bitstream_align(bs);
+    cx->has_add_terms  = bitstream_getbit(bs);
+    cx->has_mult_terms = bitstream_getbit(bs);
+    nbits = bitstream_getbits(bs, 4);
+    cx->nbits = nbits;
+    if (cx->has_mult_terms) {
+        cx->red_mult_term   = bitstream_getbits(bs, nbits);
+        cx->green_mult_term = bitstream_getbits(bs, nbits);
+        cx->blue_mult_term  = bitstream_getbits(bs, nbits);
+    }
+    if (cx->has_add_terms) {
+        cx->red_add_term   = bitstream_getbits(bs, nbits);
+        cx->green_add_term = bitstream_getbits(bs, nbits);
+        cx->blue_add_term  = bitstream_getbits(bs, nbits);
+    }
+    return 0;
+}
+
+int
+swf_cxform_build(bitstream_t *bs, swf_cxform_t *cx) {
+    int nbits;
+    bitstream_align(bs);
+    bitstream_putbit(bs, cx->has_add_terms);
+    bitstream_putbit(bs, cx->has_mult_terms);
+    nbits = cx->has_mult_terms;
+    cx->nbits = nbits;
+    if (cx->has_mult_terms) {
+        cx->red_mult_term   = bitstream_getbits(bs, nbits);
+        cx->green_mult_term = bitstream_getbits(bs, nbits);
+        cx->blue_mult_term  = bitstream_getbits(bs, nbits);
+    }
+    if (cx->has_add_terms) {
+        cx->red_add_term   = bitstream_getbits(bs, nbits);
+        cx->green_add_term = bitstream_getbits(bs, nbits);
+        cx->blue_add_term  = bitstream_getbits(bs, nbits);
+    }
+    return 0;
+}
+
+int
+swf_cxform_print(swf_cxform_t *cx, int indent_depth) {
+    print_indent(indent_depth);
+    printf("CXFORM:");
+    if (cx->has_mult_terms) {
+        printf("  MultTerm:%02x%02x%02x",
+               cx->red_mult_term, cx->green_mult_term, cx->blue_mult_term);
+    }
+    if (cx->has_add_terms) {
+        printf("  AddTerm:%02x%02x%02x",
+               cx->red_add_term, cx->green_add_term, cx->blue_add_term);
+    }
+    printf("\n");
+    return 0;
+}

Added: trunk/src/swf_cxform.h
===================================================================
--- trunk/src/swf_cxform.h	                        (rev 0)
+++ trunk/src/swf_cxform.h	2011-03-01 12:51:40 UTC (rev 371)
@@ -0,0 +1,29 @@
+/*
+  +----------------------------------------------------------------------+
+  | Author: yoya****@awm*****                                                  |
+  +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_CXFORM_H__
+#define __SWF_CXFORM_H__
+
+typedef struct swf_cxform_ {
+    unsigned char has_add_terms;
+    unsigned char has_mult_terms;
+    unsigned char nbits;
+    // multiply value
+    unsigned int red_mult_term;
+    unsigned int green_mult_term;
+    unsigned int blue_mult_term;
+    // addition value
+    unsigned int red_add_term;
+    unsigned int green_add_term;
+    unsigned int blue_add_term;
+} swf_cxform_t;
+
+
+extern int swf_cxform_parse(bitstream_t *bs, swf_cxform_t *color);
+extern int swf_cxform_build(bitstream_t *bs, swf_cxform_t *color);
+extern int swf_cxform_print(swf_cxform_t *color, int indent_depth);
+
+#endif /* __SWF_CXFORM_H__ */

Modified: trunk/src/swf_tag.c
===================================================================
--- trunk/src/swf_tag.c	2011-02-23 15:29:41 UTC (rev 370)
+++ trunk/src/swf_tag.c	2011-03-01 12:51:40 UTC (rev 371)
@@ -16,6 +16,7 @@
 #include "swf_tag_sound.h"
 #include "swf_tag_sprite.h"
 #include "swf_tag_shape.h"
+#include "swf_tag_place.h"
 #include "bitmap_util.h"
 
 swf_tag_info_t swf_tag_info_table[] = {
@@ -23,7 +24,7 @@
     { 1, "ShowFrame", NULL },
     { 2, "DefineShape", swf_tag_shape_detail_handler },
     { 3, "FreeCharacter", NULL},
-    { 4, "PlaceObject", NULL},
+    { 4, "PlaceObject", swf_tag_place_detail_handler },
     { 5, "RemoveObject", NULL},
     { 6, "DefineBitsJPEG", swf_tag_jpeg_detail_handler },
     { 7, "DefineButton", NULL},
@@ -42,7 +43,7 @@
     { 20, "DefineBitsLossless", swf_tag_lossless_detail_handler },
     { 21, "DefineBitsJPEG2", swf_tag_jpeg_detail_handler },
     { 22, "DefineShape2", swf_tag_shape_detail_handler },
-    { 26, "PlaceObject2", NULL },
+    { 26, "PlaceObject2", swf_tag_place_detail_handler },
     { 28, "RemoveObject2", NULL },
     { 32, "DefineShape3", swf_tag_shape_detail_handler },
     { 33, "DefineText2", NULL },

Added: trunk/src/swf_tag_place.c
===================================================================
--- trunk/src/swf_tag_place.c	                        (rev 0)
+++ trunk/src/swf_tag_place.c	2011-03-01 12:51:40 UTC (rev 371)
@@ -0,0 +1,268 @@
+/*
+  +----------------------------------------------------------------------+
+  | Author: yoya****@awm*****                                                  |
+  +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "bitstream.h"
+#include "swf_tag_place.h"
+#include "swf_object.h"
+
+swf_tag_detail_handler_t place_detail_handler;
+
+swf_tag_detail_handler_t *
+swf_tag_place_detail_handler(void) {
+    place_detail_handler.create   = swf_tag_place_create_detail;
+    place_detail_handler.input    = swf_tag_place_input_detail;
+    place_detail_handler.identity = NULL;
+    place_detail_handler.output   = swf_tag_place_output_detail;
+    place_detail_handler.print    = swf_tag_place_print_detail;
+    place_detail_handler.destroy  = swf_tag_place_destroy_detail;
+    return &place_detail_handler;
+}
+
+void *
+swf_tag_place_create_detail(void) {
+    swf_tag_place_detail_t *swf_tag_place;
+    swf_tag_place = calloc(sizeof(*swf_tag_place), 1);
+    if (swf_tag_place == NULL) {
+        fprintf(stderr, "ERROR: swf_tag_place_create_detail: can't calloc\n");
+        return NULL;
+    }
+    return swf_tag_place;
+}
+
+int
+swf_tag_place_input_detail(swf_tag_t *tag, struct swf_object_ *swf) {
+    swf_tag_place_detail_t *swf_tag_place = tag->detail;
+    unsigned char *data  = tag->data;
+    unsigned long length = tag->length;
+    bitstream_t *bs;
+    int ret;
+    (void) swf;
+    if (swf_tag_place == NULL) {
+        fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place == NULL\n");
+        return 1;
+    }
+    swf_tag_place->character_id = 0; // undefined
+    bs = bitstream_open();
+    bitstream_input(bs, data, length);
+
+    if (tag->tag == 4) { // PlaceObject
+        swf_tag_place->character_id = bitstream_getbytesLE(bs, 2);
+        swf_tag_place->depth = bitstream_getbytesLE(bs, 2);
+        ret = swf_matrix_parse(bs, &(swf_tag_place->matrix));
+        if (ret) {
+            fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->matrix parse failed. character_id=%d\n", swf_tag_place->character_id);
+            bitstream_close(bs);
+            return ret;
+        }
+        ret = swf_cxform_parse(bs, &(swf_tag_place->color_transform));
+        if (ret) {
+            fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->color_transform parse failed. character_id=%d\n", swf_tag_place->character_id);
+            bitstream_close(bs);
+            return ret;
+        }
+    } else if (tag->tag == 26) { // PlaceObject2
+        swf_tag_place->flag_has_clip_action = bitstream_getbit(bs);
+        swf_tag_place->flag_has_clip_depth = bitstream_getbit(bs);
+        swf_tag_place->flag_has_name = bitstream_getbit(bs);
+        swf_tag_place->flag_has_ratio = bitstream_getbit(bs);
+        swf_tag_place->flag_has_color_transform = bitstream_getbit(bs);
+        swf_tag_place->flag_has_matrix = bitstream_getbit(bs);
+        swf_tag_place->flag_has_character = bitstream_getbit(bs);
+        swf_tag_place->flag_has_movie = bitstream_getbit(bs);
+        swf_tag_place->depth = bitstream_getbytesLE(bs, 2);
+        if (swf_tag_place->flag_has_character) {
+            swf_tag_place->character_id = bitstream_getbytesLE(bs, 2);
+        }
+        if (swf_tag_place->flag_has_matrix) {
+            ret = swf_matrix_parse(bs, &(swf_tag_place->matrix));
+            if (ret) {
+                fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->matrix parse failed. character_id=%d\n", swf_tag_place->character_id);
+                bitstream_close(bs);
+                return ret;
+            }
+        }
+        if (swf_tag_place->flag_has_color_transform) {
+            ret = swf_cxform_parse(bs, &(swf_tag_place->color_transform));
+            if (ret) {
+                fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->color_transform parse failed. character_id=%d\n", swf_tag_place->character_id);
+                bitstream_close(bs);
+                return ret;
+            }
+        }
+        if (swf_tag_place->flag_has_ratio) {
+            swf_tag_place->ratio = bitstream_getbytesLE(bs, 2);
+        }
+        if (swf_tag_place->flag_has_name) {
+            swf_tag_place->name = bitstream_outputstring(bs);
+        }
+        if (swf_tag_place->flag_has_clip_depth) {
+            swf_tag_place->clip_depth = bitstream_getbytesLE(bs, 2);   
+        }
+        // TODO: clip action data for SWF 5
+        
+    } else {
+        return 1; // unknown tag;
+    }
+    bitstream_close(bs);
+    return 0;
+}
+
+unsigned char *
+swf_tag_place_output_detail(swf_tag_t *tag, unsigned long *length,
+                           struct swf_object_ *swf) {
+    swf_tag_place_detail_t *swf_tag_place = (swf_tag_place_detail_t *) tag->detail;
+    bitstream_t *bs;
+    unsigned char *data;
+    int ret;
+    (void) swf;
+    *length = 0;
+
+    //
+    bs = bitstream_open();
+    bitstream_putbytesLE(bs, swf_tag_place->character_id, 2);
+/*
+    swf_rect_build(bs, &(swf_tag_place->rect));
+
+    // DefineMorphPlace, DefineMorphPlace2
+    swf_tag_place->is_morph = (tag->tag == 46) || (tag->tag == 84);
+    // DefinePlace4, DefineMorphPlace2
+    swf_tag_place->has_strokes = (tag->tag == 83) || (tag->tag == 84);
+
+    if (swf_tag_place->is_morph) {
+        ret = swf_rect_build(bs, &(swf_tag_place->rect_morph));
+        if (ret) {
+            fprintf(stderr, "ERROR: swf_tag_place_output_detail: swf_tag_place->rect_morph build failed\n");
+            bitstream_close(bs);
+            return NULL;
+        }
+    }
+    if (swf_tag_place->has_strokes) {
+        ret = swf_rect_build(bs, &(swf_tag_place->stroke_rect));
+        if (ret) {
+            fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->stroke_rect build failed\n");
+            bitstream_close(bs);
+            return NULL;
+        }
+        if (swf_tag_place->is_morph) {
+            ret = swf_rect_build(bs, &(swf_tag_place->stroke_rect_morph));
+	    if (ret) {
+	        fprintf(stderr, "ERROR: swf_tag_place_input_detail: swf_tag_place->stroke_rect_morph build failed\n");
+	        bitstream_close(bs);
+	        return NULL;
+	    }
+        }
+        bitstream_putbits(bs, 6, swf_tag_place->define_place_reserved );
+        bitstream_putbits(bs, 1, swf_tag_place->define_place_non_scaling_strokes );
+        bitstream_putbits(bs, 1, swf_tag_place->define_place_scaling_strokes);
+    }
+    if (swf_tag_place->is_morph) {
+        bitstream_putbytesLE(bs, 4, swf_tag_place->offset_morph);
+        swf_morph_place_with_style_build(bs, &swf_tag_place->morph_place_with_style, tag);
+    } else {
+        ret = swf_place_with_style_build(bs, &swf_tag_place->place_with_style, tag);
+        if (ret) {
+            fprintf(stderr, "swf_tag_place_output_detail: swf_place_with_style_build failed\n");
+            bitstream_close(bs);
+            return NULL;
+        }
+    }
+*/
+    data = bitstream_steal(bs, length);
+    bitstream_close(bs);
+    return data;
+}
+
+void
+swf_tag_place_print_detail(swf_tag_t *tag,
+                           struct swf_object_ *swf, int indent_depth) {
+    swf_tag_place_detail_t *swf_tag_place = (swf_tag_place_detail_t *) tag->detail;
+    (void) swf;
+    print_indent(indent_depth);
+    if (tag->tag == 4) { // PlaceObject
+        printf("character_id=%d  depth=%d\n",
+               swf_tag_place->character_id, swf_tag_place->depth);
+        swf_matrix_print(&(swf_tag_place->matrix), indent_depth);
+        swf_cxform_print(&(swf_tag_place->color_transform), indent_depth);
+    } else if (tag->tag == 26) { // PlaceObject2
+        printf("(clipact,clipdepth,name,ratio,coltrans,mat,cid,movie)=(%d,%d,%d,%d,%d,%d,%d,%d)\n",
+               swf_tag_place->flag_has_clip_action,
+               swf_tag_place->flag_has_clip_depth,
+               swf_tag_place->flag_has_name,
+               swf_tag_place->flag_has_ratio,
+               swf_tag_place->flag_has_color_transform,
+               swf_tag_place->flag_has_matrix,
+               swf_tag_place->flag_has_character,
+               swf_tag_place->flag_has_movie);
+        if (swf_tag_place->flag_has_character) {
+            print_indent(indent_depth);
+            printf("character_id=%d\n", swf_tag_place->character_id);
+        }
+        if (swf_tag_place->flag_has_matrix) {
+            swf_matrix_print(&(swf_tag_place->matrix), indent_depth);
+        }
+        if (swf_tag_place->flag_has_color_transform) {
+            swf_cxform_print(&(swf_tag_place->color_transform), indent_depth);
+        }
+        if (swf_tag_place->flag_has_ratio) {
+            print_indent(indent_depth);
+            printf("ratio=%d\n", swf_tag_place->ratio);
+        }
+        if (swf_tag_place->flag_has_name) {
+            print_indent(indent_depth);
+            printf("name=%s\n", swf_tag_place->name);
+        }
+        if (swf_tag_place->flag_has_clip_depth) {
+            print_indent(indent_depth);
+            printf("ratio=%d\n", swf_tag_place->clip_depth);
+        }
+    } else {
+        fprintf(stderr, "Illegal tag no(%d)\n", tag->tag);
+    }
+
+    /*
+    
+    print_indent(indent_depth);
+
+    if (swf_tag_place->is_morph) {
+        swf_rect_print(&(swf_tag_place->rect_morph), indent_depth);
+    }
+    if (swf_tag_place->has_strokes) {
+        swf_rect_print(&(swf_tag_place->stroke_rect), indent_depth);
+        if (swf_tag_place->is_morph) {
+            swf_rect_print(&(swf_tag_place->stroke_rect_morph), indent_depth);
+        }
+        print_indent(indent_depth);
+        printf("define_place_non_scaling_strokes=%d define_place_scaling_strokes=%d\n",
+               swf_tag_place->define_place_non_scaling_strokes,
+               swf_tag_place->define_place_scaling_strokes);
+    }
+    if (swf_tag_place->is_morph) {
+        print_indent(indent_depth);
+        printf("offset_morph=%lu\n", swf_tag_place->offset_morph);
+        swf_morph_place_with_style_print(&swf_tag_place->morph_place_with_style,
+                                         indent_depth, tag);
+    } else {
+        swf_place_with_style_print(&swf_tag_place->place_with_style,
+                                   indent_depth, tag);
+    }
+    */
+    return ;
+}
+
+void
+swf_tag_place_destroy_detail(swf_tag_t *tag) {
+    swf_tag_place_detail_t *swf_tag_place = (swf_tag_place_detail_t *) tag->detail;
+    if (swf_tag_place) {
+        if (swf_tag_place->name) {
+            free(swf_tag_place->name);
+        }
+        free(swf_tag_place);
+        tag->detail = NULL;
+    }
+    return ;
+}

Added: trunk/src/swf_tag_place.h
===================================================================
--- trunk/src/swf_tag_place.h	                        (rev 0)
+++ trunk/src/swf_tag_place.h	2011-03-01 12:51:40 UTC (rev 371)
@@ -0,0 +1,45 @@
+/*
+  +----------------------------------------------------------------------+
+  | Author: yoya****@awm*****                                                  |
+  +----------------------------------------------------------------------+
+*/
+
+#ifndef __SWF_TAG_PLACE__H__
+#define __SWF_TAG_PLACE__H__
+
+#include "swf_matrix.h"
+#include "swf_cxform.h"
+#include "swf_tag.h"
+
+typedef struct swf_tag_place_detail_ {
+    int character_id; //  Shape2 optional.
+    int flag_has_clip_action;
+    int flag_has_clip_depth;
+    int flag_has_name;
+    int flag_has_ratio;
+    int flag_has_color_transform;
+    int flag_has_matrix;
+    int flag_has_character;
+    int flag_has_movie;
+    int depth;
+    swf_matrix_t matrix;
+    swf_cxform_t color_transform;
+    int ratio;
+    char *name;
+    int clip_depth;
+} swf_tag_place_detail_t;
+
+extern swf_tag_detail_handler_t *swf_tag_place_detail_handler(void);
+
+extern void *swf_tag_place_create_detail(void);
+extern int swf_tag_place_input_detail(swf_tag_t *tag, struct swf_object_ *swf);
+extern unsigned char *swf_tag_place_output_detail(swf_tag_t *tag,
+                                                   unsigned long *length,
+                                                   struct swf_object_ *swf);
+extern void swf_tag_place_print_detail(swf_tag_t *tag,
+                                       struct swf_object_ *swf,
+                                       int indent_depth);
+extern void swf_tag_place_destroy_detail(swf_tag_t *tag);
+
+#endif /* __SWF_TAG_PLACE__H__ */
+



Swfed-svn メーリングリストの案内
Back to archive index