[Swfed-svn] swfed-svn [437] - 不要な Shape を削除する際に関連するビットマップも削除する処理を実装

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2011年 3月 21日 (月) 02:03:09 JST


Revision: 437
          http://sourceforge.jp/projects/swfed/svn/view?view=rev&revision=437
Author:   yoya
Date:     2011-03-21 02:03:09 +0900 (Mon, 21 Mar 2011)

Log Message:
-----------
- 不要な Shape を削除する際に関連するビットマップも削除する処理を実装
- 差し替え SWF の JpegTables はとりあえず無視するようにした。(SWF に JpegTables が 2つあるのはマズいので)

Modified Paths:
--------------
    trunk/src/swf_object.c


-------------- next part --------------
Modified: trunk/src/swf_object.c
===================================================================
--- trunk/src/swf_object.c	2011-03-18 02:24:32 UTC (rev 436)
+++ trunk/src/swf_object.c	2011-03-20 17:03:09 UTC (rev 437)
@@ -1018,7 +1018,9 @@
     swf_tag_info_t *tag_info = NULL;
     swf_tag_detail_handler_t *detail_handler = NULL;
     trans_table_t *cid_trans_table;
+#ifdef SWF_OBJECT_UNUSED_CID_PURGE
     trans_table_t *orig_sprite_refcid_trans_table;
+#endif // SWF_OBJECT_UNUSED_CID_PURGE
 #ifdef SWF_OBJECT_DEPTH_RENUMBER
     trans_table_t *depth_trans_table;
 #endif // SWF_OBJECT_DEPTH_RENUMBER
@@ -1026,6 +1028,7 @@
         fprintf(stderr, "swf_object_replace_movieclip: swf == NULL\n");
         return 1;
     }
+    // インスタンス名から PlaceObject を探し、参照している CID を取得する
     for (tag=swf->tag ; tag ; tag=tag->next) {
         if (tag->tag == 26) { // PlaceObject2
             cid = swf_tag_place_get_cid_by_instance_name(tag, instance_name, instance_name_len, swf);
@@ -1039,6 +1042,8 @@
                 "swf_object_replace_movieclip: place cid(%d) <= 0\n", cid);
         return 1; // not found instance name;
     }
+
+    // CID で DefineSprite を探す
     for (tag=swf->tag ; tag ; tag=tag->next) {
         if (isSpriteTag(tag->tag)) {
             if (swf_tag_get_cid(tag) ==  cid) {
@@ -1054,31 +1059,40 @@
         return 1; // not found instance name;
     }
 
+    // MC に差し替える SWF データ
     swf4sprite = swf_object_open();
     ret = swf_object_input(swf4sprite, swf_data, swf_data_len);
     if (ret) {
         fprintf(stderr, "swf_object_replace_movieclip: swf_object_input (swf_data_len=%d) failed\n", swf_data_len);
         return ret;
     }
-    // 既存の CID
-    cid_trans_table = trans_table_open();
-#ifdef SWF_OBJECT_DEPTH_RENUMBER
-    depth_trans_table = trans_table_open();
-#endif // SWF_OBJECT_DEPTH_RENUMBER
+
+#ifdef SWF_OBJECT_UNUSED_CID_PURGE
     orig_sprite_refcid_trans_table = trans_table_open();
+    // Sprite タグから参照するコンテンツを削除する
+    swf_tag_sprite = swf_tag_create_input_detail(sprite_tag, NULL);
+    trans_table_reserve_refcid_recursive(swf_tag_sprite->tag, orig_sprite_refcid_trans_table);
+//    trans_table_print(orig_sprite_refcid_trans_table);
     for (tag=swf->tag ; tag ; tag=tag->next) {
         int cid;
         cid = swf_tag_get_cid(tag);
-        if (cid > 0) {
-            trans_table_set(cid_trans_table, cid, TRANS_TABLE_RESERVE_ID);
+        if ((cid > 0) && (trans_table_get(orig_sprite_refcid_trans_table, cid) == TRANS_TABLE_RESERVE_ID)) {
+            // Shape が参照するビットマップも後で削除
+            if (isShapeTag(tag->tag)) {
+                int bitmap_id;
+                bitmap_id = swf_tag_shape_bitmap_get_refcid(tag);
+                trans_table_set(orig_sprite_refcid_trans_table, bitmap_id, TRANS_TABLE_RESERVE_ID);
+            }
+            // タグ削除処理
+            prev_tag->next = tag->next;
+            swf_tag_destroy(tag);
+            tag = prev_tag;
+        } else {
+            prev_tag = tag;
         }
     }
-#ifdef SWF_OBJECT_UNUSED_CID_PURGE
-    // Sprite タグから参照するコンテンツを削除する
-    swf_tag_sprite = swf_tag_create_input_detail(sprite_tag, NULL);
-    trans_table_reserve_refcid_recursive(swf_tag_sprite->tag, orig_sprite_refcid_trans_table);
+    // Shape が参照するビットマップを削除
     for (tag=swf->tag ; tag ; tag=tag->next) {
-        int cid;
         cid = swf_tag_get_cid(tag);
         if ((cid > 0) && (trans_table_get(orig_sprite_refcid_trans_table, cid) == TRANS_TABLE_RESERVE_ID)) {
             prev_tag->next = tag->next;
@@ -1088,8 +1102,34 @@
             prev_tag = tag;
         }
     }
+
+    // prev_sprite_tag を取り直す。(PURGE される事があるので)
+    for (tag=swf->tag ; tag ; tag=tag->next) {
+        if (isSpriteTag(tag->tag)) {
+            if (swf_tag_get_cid(tag) == sprite_cid) {
+                break;
+            }
+        }
+        prev_sprite_tag = tag;
+    }
+    // 
 #endif // SWF_OBJECT_UNUSED_CID_PURGE
     
+#ifdef SWF_OBJECT_DEPTH_RENUMBER
+    depth_trans_table = trans_table_open();
+#endif // SWF_OBJECT_DEPTH_RENUMBER
+    
+    // 既存の CID
+    cid_trans_table = trans_table_open();
+    for (tag=swf->tag ; tag ; tag=tag->next) {
+        int cid;
+        cid = swf_tag_get_cid(tag);
+        if (cid > 0) {
+            trans_table_set(cid_trans_table, cid, TRANS_TABLE_RESERVE_ID);
+        }
+    }
+//    trans_table_print(cid_trans_table);
+    
     // Sprite タグの中を綺麗にする
     tag_info = get_swf_tag_info(sprite_tag->tag);
     detail_handler = tag_info->detail_handler();
@@ -1119,13 +1159,13 @@
           case 56: // Export
           case 69: // FileAttributes
           case 74: // CSMTextSettings
+          case 8: // JPEGTables // XXX
               ;
             break;
             // Character Tag
           case 2: // DefineShape
           case 6: // DefineBitsJPEG
           case 7: // DefineButton
-          case 8: // JPEGTables
           case 10: // DefineFont
           case 11: // DefineText
           case 13: // DefineFontInfo
@@ -1184,9 +1224,7 @@
                   }
                   trans_table_replace_refcid_recursive(s->tag, cid_trans_table);
               }
-              // TODO depth が被らないように。
-              ;
-              // Sprite の前に CID が被らないように展開
+              // Sprite の前に展開
               prev_sprite_tag->next = swf_tag_move(tag);
               prev_sprite_tag = prev_sprite_tag->next;
               prev_sprite_tag->next = sprite_tag;
@@ -1238,7 +1276,9 @@
     trans_table_close(depth_trans_table);
 #endif // SWF_OBJECT_DEPTH_RENUMBER
     trans_table_close(cid_trans_table);
+#ifdef SWF_OBJECT_UNUSED_CID_PURGE
     trans_table_close(orig_sprite_refcid_trans_table);
+#endif// SWF_OBJECT_UNUSED_CID_PURGE
     swf_object_close(swf4sprite);
     return 0;
 }



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