Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/writers/SWFTagDumper.java


1   /****************************************************************
2    * Copyright (c) 2001, David N. Main, All rights reserved.
3    * 
4    * Redistribution and use in source and binary forms, with or
5    * without modification, are permitted provided that the 
6    * following conditions are met:
7    *
8    * 1. Redistributions of source code must retain the above 
9    * copyright notice, this list of conditions and the following 
10   * disclaimer. 
11   * 
12   * 2. Redistributions in binary form must reproduce the above 
13   * copyright notice, this list of conditions and the following 
14   * disclaimer in the documentation and/or other materials 
15   * provided with the distribution.
16   * 
17   * 3. The name of the author may not be used to endorse or 
18   * promote products derived from this software without specific 
19   * prior written permission. 
20   * 
21   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 
22   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
23   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
24   * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
25   * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
27   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
28   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
29   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
30   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
31   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
32   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************/
34  package com.anotherbigidea.flash.writers;
35  
36  import java.io.FileInputStream;
37  import java.io.IOException;
38  import java.io.InputStream;
39  import java.io.OutputStream;
40  import java.io.PrintWriter;
41  import java.util.Enumeration;
42  import java.util.Vector;
43  
44  import com.anotherbigidea.flash.SWFConstants;
45  import com.anotherbigidea.flash.interfaces.SWFActions;
46  import com.anotherbigidea.flash.interfaces.SWFFileSignature;
47  import com.anotherbigidea.flash.interfaces.SWFShape;
48  import com.anotherbigidea.flash.interfaces.SWFTagTypes;
49  import com.anotherbigidea.flash.interfaces.SWFTags;
50  import com.anotherbigidea.flash.interfaces.SWFText;
51  import com.anotherbigidea.flash.interfaces.SWFVectors;
52  import com.anotherbigidea.flash.readers.SWFReader;
53  import com.anotherbigidea.flash.readers.TagParser;
54  import com.anotherbigidea.flash.structs.AlphaColor;
55  import com.anotherbigidea.flash.structs.AlphaTransform;
56  import com.anotherbigidea.flash.structs.ButtonRecord;
57  import com.anotherbigidea.flash.structs.ButtonRecord2;
58  import com.anotherbigidea.flash.structs.Color;
59  import com.anotherbigidea.flash.structs.ColorTransform;
60  import com.anotherbigidea.flash.structs.Matrix;
61  import com.anotherbigidea.flash.structs.Rect;
62  import com.anotherbigidea.flash.structs.SoundInfo;
63  import com.anotherbigidea.util.Hex;
64  
65  /**
66   * An implementation of the SWFTagTypes interface that produces a debug dump
67   */
68  public class SWFTagDumper 
69    implements SWFTagTypes, SWFShape, SWFText, SWFFileSignature 
70  {
71      protected PrintWriter writer;
72      protected String dashes = "---------------";
73      protected boolean dumpHex;
74      protected String indent = "";
75      protected boolean decompileActions = false;
76      
77      /** 
78       * Dump to System.out
79       * @param dumpHex if true then binary data will dumped as hex - otherwise skipped
80       */
81      public SWFTagDumper( boolean dumpHex, boolean decompileActions )
82      {
83          this( System.out, dumpHex, decompileActions );
84      }
85      
86      /**
87       * Dump to the given output stream
88       * @param dumpHex if true then binary data will dumped as hex - otherwise skipped
89       */
90      public SWFTagDumper( OutputStream out, 
91                           boolean dumpHex, 
92                           boolean decompileActions )
93      {
94          writer = new PrintWriter( out );
95          this.dumpHex = dumpHex;
96          this.decompileActions = decompileActions;
97      }
98      
99      public SWFTagDumper( PrintWriter writer, 
100                          boolean dumpHex, 
101                          boolean decompileActions )
102     {
103         this.writer = writer;
104         this.dumpHex = dumpHex;
105         this.decompileActions = decompileActions;
106     }
107 
108   /**
109    * @see SWFFileSignature#signature(String)
110    */
111   public void signature( String sig ) {
112     println( "signature: " + sig );
113   }
114 
115     protected void println( String line )
116     {
117         writer.println( indent + line );
118     }
119     
120     /**
121      * SWFTags interface
122      */    
123     public void tag( int tagType, boolean longTag, byte[] contents ) 
124         throws IOException
125     {
126         println( "Tag " + tagType + " length=" + contents.length );
127         
128         if( dumpHex )
129         {
130             Hex.dump( writer, contents, 0L, indent + "    ", false );
131             println( dashes );
132         }
133     }
134 
135     /**
136      * SWFHeader interface.
137      */
138     public void header( int version, long length,
139                         int twipsWidth, int twipsHeight,
140                         int frameRate, int frameCount ) throws IOException
141     {
142         println( "header: version=" + version + 
143                  " length=" + length + " width=" + twipsWidth +
144                  " height=" + twipsHeight + " rate=" + frameRate +
145                  " frame-count=" + frameCount );
146     }
147     
148     /**
149      * SWFTagTypes interface
150      */
151     public void tagEnd() throws IOException
152     {
153         println( "end" );
154         println( dashes );
155     }
156 
157     /**
158      * SWFTagTypes interface
159      */
160     public void tagStartSound( int soundId, SoundInfo info ) throws IOException
161     {
162         println( "start-sound id=" + soundId + " " + info );
163     }
164     
165     /**
166      * SWFTagTypes interface
167      */
168     public void tagSoundStreamHead( 
169         int playbackFrequency, boolean playback16bit, boolean playbackStereo,
170         int streamFormat, int streamFrequency, boolean stream16bit, boolean streamStereo,
171         int averageSampleCount ) throws IOException
172     {
173         printSoundStreamHead( "sound-stream-head", 
174             playbackFrequency, playback16bit, playbackStereo,
175             streamFormat, streamFrequency, stream16bit, streamStereo,
176             averageSampleCount );
177     }
178     
179     /**
180      * SWFTagTypes interface
181      */
182     public void tagSoundStreamHead2( 
183         int playbackFrequency, boolean playback16bit, boolean playbackStereo,
184         int streamFormat, int streamFrequency, boolean stream16bit, boolean streamStereo,
185         int averageSampleCount ) throws IOException
186     {
187         printSoundStreamHead( "sound-stream-head-2", 
188             playbackFrequency, playback16bit, playbackStereo,
189             streamFormat, streamFrequency, stream16bit, streamStereo,
190             averageSampleCount );
191     }
192     
193     public void printSoundStreamHead( String name,
194         int playbackFrequency, boolean playback16bit, boolean playbackStereo,
195         int streamFormat, int streamFrequency, boolean stream16bit, boolean streamStereo,
196         int averageSampleCount ) throws IOException
197     {
198         String playFreq = "5.5";
199         if( playbackFrequency == SWFConstants.SOUND_FREQ_11KHZ ) playFreq = "11";
200         if( playbackFrequency == SWFConstants.SOUND_FREQ_22KHZ ) playFreq = "22";
201         if( playbackFrequency == SWFConstants.SOUND_FREQ_44KHZ ) playFreq = "44";
202         
203         String streamFreq = "5.5";
204         if( streamFrequency == SWFConstants.SOUND_FREQ_11KHZ ) streamFreq = "11";
205         if( streamFrequency == SWFConstants.SOUND_FREQ_22KHZ ) streamFreq = "22";
206         if( streamFrequency == SWFConstants.SOUND_FREQ_44KHZ ) streamFreq = "44";        
207         
208         String format = "RawSamples";
209         if( streamFormat == SWFConstants.SOUND_FORMAT_ADPCM ) format = "ADPCM";
210         if( streamFormat == SWFConstants.SOUND_FORMAT_MP3   ) format = "MP3";
211         
212         println( name + " play at " + playFreq + "kHz stereo=" + playbackStereo +
213                  " 16bit=" + playback16bit + " | Stream at " + streamFreq +
214                  "kHz format=" + format + " stereo=" + streamStereo +
215                  " 16bit=" + stream16bit + " Avg-Samples=" + averageSampleCount );
216     }
217     
218     
219     /**
220      * SWFTagTypes interface
221      */
222     public void tagSoundStreamBlock( byte[] soundData ) throws IOException
223     {
224         println( "sound-stream-block" );
225         
226         if( dumpHex )
227         {
228             Hex.dump( writer, soundData, 0L, indent + "    ", false );
229             println( dashes );
230         }        
231     }    
232     
233     /**
234      * SWFTagTypes interface
235      */
236     public void tagSerialNumber( String serialNumber ) throws IOException
237     {
238         println( "serial number =" + serialNumber );       
239     }    
240                                                               
241     
242     /**
243      * SWFTagTypes interface
244      */
245     public void tagGenerator( byte[] data ) throws IOException
246     {
247         println( "generator tag" );
248         
249         if( dumpHex )
250         {
251             Hex.dump( writer, data, 0L, indent + "    ", false );
252             println( dashes );
253         }        
254     }       
255     
256     /**
257      * SWFTagTypes interface
258      */
259     public void tagGeneratorText( byte[] data ) throws IOException
260     {
261         println( "generator text" );
262         
263         if( dumpHex )
264         {
265             Hex.dump( writer, data, 0L, indent + "    ", false );
266             println( dashes );
267         }        
268     }        
269     
270     /**
271      * SWFTagTypes interface
272      */
273     public void tagGeneratorFont( byte[] data ) throws IOException
274     {
275         println( "generator font" );
276         
277         if( dumpHex )
278         {
279             Hex.dump( writer, data, 0L, indent + "    ", false );
280             println( dashes );
281         }        
282     }    
283     
284     /**
285      * SWFTagTypes interface
286      */
287     public void tagGeneratorCommand( byte[] data ) throws IOException
288     {
289         println( "generator command" );
290         
291         if( dumpHex )
292         {
293             Hex.dump( writer, data, 0L, indent + "    ", false );
294             println( dashes );
295         }        
296     }            
297 
298     /**
299      * SWFTagTypes interface
300      */
301     public void tagNameCharacter( byte[] data ) throws IOException
302     {
303         println( "generator name character" );
304         
305         if( dumpHex )
306         {
307             Hex.dump( writer, data, 0L, indent + "    ", false );
308             println( dashes );
309         }        
310     }                
311     
312     /**
313      * SWFTagTypes interface
314      */
315     public void tagDefineBits( int id, byte[] imageData ) throws IOException
316     {
317         println( "jpeg bits" );
318         
319         if( dumpHex )
320         {
321             Hex.dump( writer, imageData, 0L, indent + "    ", false );
322             println( dashes );
323         }        
324     }            
325     
326     /**
327      * SWFTagTypes interface
328      */
329     public void tagJPEGTables( byte[] jpegEncodingData ) throws IOException
330     {
331         println( "jpeg encoding data" );
332         
333         if( dumpHex )
334         {
335             Hex.dump( writer, jpegEncodingData, 0L, indent + "    ", false );
336             println( dashes );
337         }        
338     }                
339 
340     /**
341      * SWFTagTypes interface
342      */
343     public void tagDefineBitsJPEG3( int id, byte[] imageData, byte[] alphaData ) throws IOException
344     {
345         println( "jpeg with alpha" );
346         
347         if( dumpHex )
348         {
349             Hex.dump( writer, imageData, 0L, indent + "    ", false );
350             println( "--- Alpha Channel follows ---" );
351             Hex.dump( writer, alphaData, 0L, indent + "    ", false );
352             println( dashes );
353         }         
354     }                
355     
356     /**
357      * SWFTagTypes interface
358      */
359     public void tagDefineSound( int id, int format, int frequency,
360                                 boolean bits16, boolean stereo,
361                                 int sampleCount, byte[] soundData ) throws IOException
362     {
363         String freq = "5.5";
364         if( frequency == SWFConstants.SOUND_FREQ_11KHZ ) freq = "11";
365         if( frequency == SWFConstants.SOUND_FREQ_22KHZ ) freq = "22";
366         if( frequency == SWFConstants.SOUND_FREQ_44KHZ ) freq = "44";        
367         
368         String formatS = "RawSamples";
369         if( format == SWFConstants.SOUND_FORMAT_ADPCM ) formatS = "ADPCM";
370         if( format == SWFConstants.SOUND_FORMAT_MP3   ) formatS = "MP3";        
371         
372         
373         println( "define sound: id=" + id + " format=" + formatS + 
374                  " freq=" + freq + "kHz 16bit=" + bits16 +
375                  " stereo=" + stereo + " samples=" + sampleCount );
376         
377         if( dumpHex )
378         {
379             Hex.dump( writer, soundData, 0L, indent + "    ", false );
380             println( dashes );
381         }        
382     }                
383     
384     /**
385      * SWFTagTypes interface
386      */
387     public void tagDefineButtonSound( int buttonId,
388                     int rollOverSoundId, SoundInfo rollOverSoundInfo,
389                     int rollOutSoundId,  SoundInfo rollOutSoundInfo,
390                     int pressSoundId,    SoundInfo pressSoundInfo,
391                     int releaseSoundId,  SoundInfo releaseSoundInfo )
392         throws IOException
393     {
394         println( "define button sound: id=" + buttonId );
395         println( "    roll-over sound=" + rollOverSoundId + " " + rollOverSoundInfo );
396         println( "    roll-out  sound=" + rollOutSoundId  + " " + rollOutSoundInfo );
397         println( "    press     sound=" + pressSoundId    + " " + pressSoundInfo );
398         println( "    release   sound=" + releaseSoundId  + " " + releaseSoundInfo );       
399     }                
400     
401     /**
402      * SWFTagTypes interface
403      */
404     public void tagShowFrame() throws IOException
405     {
406         println( "---------- frame ----------" );
407     }
408     
409     /**
410      * SWFTagTypes interface
411      */
412     public SWFActions tagDoAction() throws IOException
413     {
414         println( "actions:" );
415         
416         ActionTextWriter acts = new ActionTextWriter( writer );
417         acts.indent = "    " + indent ;
418         return acts;
419     }
420     
421   /**
422    * SWFTagTypes interface
423    */
424   public SWFActions tagDoInitAction( int spriteId ) throws IOException
425   {
426     println( "init actions for sprite " + spriteId + ":" );
427         
428     ActionTextWriter acts = new ActionTextWriter( writer );
429     acts.indent = "    " + indent ;
430     return acts;
431   }
432     
433     /**
434      * SWFTagTypes interface
435      */
436     public SWFShape tagDefineShape( int id, Rect outline ) throws IOException
437     {
438         println( "shape id=" + id + "   " + outline );
439         return this;
440     }
441     
442     
443     /**
444      * SWFTagTypes interface
445      */
446     public SWFShape tagDefineShape2( int id, Rect outline ) throws IOException
447     {
448         println( "shape2 id=" + id + "   " + outline );
449         return this;
450     }
451     
452     /**
453      * SWFTagTypes interface
454      */
455     public SWFShape tagDefineShape3( int id, Rect outline ) throws IOException
456     {
457         println( "shape3 id=" + id + "   " + outline );
458         return this;
459 
460     }    
461     
462     /**
463      * SWFTagTypes interface
464      */    
465     public void tagFreeCharacter( int charId ) throws IOException 
466     {
467         println( "free character id=" + charId );
468     }
469     
470     /**
471      * SWFTagTypes interface
472      */    
473     public void tagPlaceObject( int charId, int depth, 
474                                 Matrix matrix, AlphaTransform cxform ) 
475         throws IOException
476     {
477         println( "place-object id=" + charId + 
478                  " depth=" + depth + "  " + matrix + "  " + cxform );
479     }
480     
481     /**
482      * SWFTagTypes interface
483      */    
484     public SWFActions tagPlaceObject2( boolean isMove,
485                                        int clipDepth,
486                                        int depth,
487                                        int charId,
488                                        Matrix matrix,
489                                        AlphaTransform cxform,
490                                        int ratio,
491                                        String name,
492                                        int clipActionFlags )  
493         throws IOException    
494     {
495         println( "place-object2 move=" + isMove +
496                  " id=" + charId +                         
497                  " depth=" + depth + 
498                  " clip=" + clipDepth +
499                  " ratio=" + ratio +
500                  " name=" + name +
501                  "  " + matrix + "  " + cxform );
502         
503         if( clipActionFlags != 0 )
504         {
505             println( "  clip-actions:" );
506             
507             ActionTextWriter acts = new ActionTextWriter( writer );
508             acts.indent = "    " + indent ;
509             return acts;
510         }
511         
512         return null;
513     }
514         
515     /**
516      * SWFTagTypes interface
517      */ 
518     public void tagRemoveObject( int charId, int depth ) throws IOException
519     {
520         println( "remove-object id=" + charId + " depth=" + depth );
521     }
522         
523     /**
524      * SWFTagTypes interface
525      */ 
526     public void tagRemoveObject2(int depth ) throws IOException
527     {
528         println( "remove-object2 depth=" + depth );
529     }
530 
531     /**
532      * SWFTagTypes interface
533      */ 
534     public void tagSetBackgroundColor( Color color ) throws IOException
535     {
536         println( "background-color  " + color );        
537     }
538 
539     /**
540      * SWFTagTypes interface
541      */ 
542     public void tagFrameLabel( String label ) throws IOException
543     {
544         println( "frame-label " + label );
545     }
546     
547   /**
548    * SWFTagTypes interface
549    */     
550   public void tagFrameLabel( String label, boolean isAnchor ) throws IOException {    
551     println( "frame-label " + label + ( isAnchor ? " (anchor)" : "") );
552   }     
553     
554     /**
555      * SWFTagTypes interface
556      */ 
557     public SWFTagTypes tagDefineSprite( int id ) throws IOException
558     {
559         println( "sprite id=" + id );
560         
561         SWFTagDumper dumper = new SWFTagDumper( writer, dumpHex, decompileActions );
562         dumper.indent = indent + "    ";
563         return dumper;
564     }
565     
566     /**
567      * SWFTagTypes interface
568      */ 
569     public void tagProtect( byte[] password ) throws IOException
570     {
571         println( "protect" );
572     }
573     
574     /**
575      * SWFTagTypes interface
576      */ 
577     public void tagEnableDebug( byte[] password ) throws IOException
578     {
579         println( "enable-debug" );        
580     }
581         
582   /**
583    * SWFTagTypes interface
584    */ 
585   public void tagEnableDebug2( byte[] password ) throws IOException
586   {
587     println( "enable-debug-2" );        
588   }
589         
590     /**
591      * SWFTagTypes interface
592      */ 
593     public SWFVectors tagDefineFont( int id, int numGlyphs ) throws IOException
594     {
595         println( "font id=" + id );
596         return this;
597     }
598 
599     /**
600      * SWFTagTypes interface
601      */ 
602     public void tagDefineFontInfo( int fontId, String fontName, int flags, int[] codes )
603         throws IOException
604     {
605         println( "font-info id=" + fontId + " name=" + fontName + 
606                  " flags=" + Integer.toBinaryString( flags ) + " codes=" + codes.length );
607     }
608 
609   /**
610    * SWFTagTypes interface
611    */ 
612   public void tagDefineFontInfo2( int fontId, String fontName, int flags, int[] codes, int languageCode )
613     throws IOException
614   {
615     println( "font-info2 id=" + fontId + " name=" + fontName + 
616          " flags=" + Integer.toBinaryString( flags ) + 
617                  " codes=" + codes.length + " language=" + languageCode );
618   }
619     
620     /**
621      * SWFTagTypes interface
622      */ 
623     public SWFVectors tagDefineFont2( int id, int flags, String name, int numGlyphs,
624                                       int ascent, int descent, int leading,
625                                       int[] codes, int[] advances, Rect[] bounds,
626                                       int[] kernCodes1, int[] kernCodes2,
627                                       int[] kernAdjustments ) throws IOException
628     {
629         println( "font2 id=" + id + " flags=" + Integer.toBinaryString( flags ) +
630                  " name=" + name + " ascent=" + ascent + " descent=" + descent +
631                  " leading=" + leading + " has-kerns=" + (kernCodes1 != null));
632         
633         return this;
634     }
635     
636     /**
637      * SWFTagTypes interface
638      */ 
639     public void tagDefineTextField( int fieldId, String fieldName,
640                     String initialText, Rect boundary, int flags,
641                     AlphaColor textColor, int alignment, int fontId, int fontSize, 
642                     int charLimit, int leftMargin, int rightMargin, int indentation,
643                     int lineSpacing ) 
644         throws IOException
645     {
646       if( initialText != null ) {
647         initialText = initialText.replace( '\r', ' ' );
648       initialText = initialText.replace( '\n', ' ' );
649       initialText = initialText.replace( '\b', ' ' );
650        }
651       
652         println( "edit-field id=" + fieldId + " name=" + fieldName +
653                  " text=" + initialText + " font=" + fontId + " size=" + fontSize +
654                  " chars=" + charLimit + " left=" + leftMargin +
655                  " right=" + rightMargin + " indent=" + indentation +
656                  " spacing=" + lineSpacing + " alignment=" + alignment +
657                  " flags=" + Integer.toBinaryString( flags ) +
658                  " " + textColor );        
659     }
660 
661     /**
662      * SWFTagTypes interface
663      */ 
664     public SWFText tagDefineText( int id, Rect bounds, Matrix matrix )
665         throws IOException
666     { 
667         println( "text id=" + id + " " + bounds + " " + matrix );
668         return this;
669     }
670 
671     /**
672      * SWFTagTypes interface
673      */ 
674     public SWFText tagDefineText2( int id, Rect bounds, Matrix matrix ) throws IOException
675     { 
676         println( "text2 id=" + id + " " + bounds + " " + matrix );
677         return this;
678     }
679     
680     /**
681      * SWFTagTypes interface
682      */ 
683     public SWFActions tagDefineButton( int id, Vector buttonRecords )
684         throws IOException
685     {
686         println( "button id=" + id );
687         
688         for( Enumeration enum = buttonRecords.elements(); enum.hasMoreElements(); )
689         {
690             ButtonRecord rec = (ButtonRecord)enum.nextElement();
691             println( "  " + rec );
692         }
693 
694         println( "  actions:" );
695         
696         ActionTextWriter acts = new ActionTextWriter( writer );
697         acts.indent = "    " + indent ;
698         return acts;
699     }
700     
701     /**
702      * SWFTagTypes interface
703      */ 
704     public void tagButtonCXForm( int buttonId, ColorTransform transform ) 
705         throws IOException
706     {
707         println( "button-cxform id=" + buttonId + "  " + transform );
708     }
709         
710     /**
711      * SWFTagTypes interface
712      */ 
713     public SWFActions tagDefineButton2( int id, 
714                                         boolean trackAsMenu, 
715                                         Vector buttonRecord2s )
716         throws IOException
717     {
718         println( "button2 id=" + id + " track-as-menu=" + trackAsMenu );
719         
720         for( Enumeration enum = buttonRecord2s.elements(); enum.hasMoreElements(); )
721         {
722             ButtonRecord2 rec = (ButtonRecord2)enum.nextElement();
723             println( "  " + rec );
724         }
725 
726         println( "  actions:" );
727         
728         ActionTextWriter acts = new ActionTextWriter( writer );
729         acts.indent = "    " + indent ;
730         return acts;
731             
732     }
733 
734     /**
735      * SWFTagTypes interface
736      */ 
737     public void tagExport( String[] names, int[] ids ) throws IOException
738     {
739         println( "export" );
740         
741         for( int i = 0; i < names.length && i < ids.length; i++ )
742         {
743             println( "  id=" + ids[i] + " name=" + names[i] );
744         }
745     }
746     
747     /**
748      * SWFTagTypes interface
749      */ 
750     public void tagImport( String movieName, String[] names, int[] ids ) 
751         throws IOException
752     {
753         println( "import library-movie=" + movieName );
754         
755         for( int i = 0; i < names.length && i < ids.length; i++ )
756         {
757             println( "  id=" + ids[i] + " name=" + names[i] );
758         }
759     }
760     
761     /**
762      * SWFTagTypes interface
763      */ 
764     public void tagDefineQuickTimeMovie( int id, String filename ) throws IOException
765     {
766         println( "quicktime-movie id=" + id + " name=" + filename );
767     }
768     
769     /**
770      * SWFTagTypes interface
771      */ 
772     public void tagDefineBitsJPEG2( int id, byte[] data ) throws IOException
773     {
774         println( "jpeg2 id=" + id );
775 
776         if( dumpHex )
777         {
778             Hex.dump( writer, data, 0L, indent + "    ", false );
779             println( dashes );
780         }
781     }
782     
783     /**
784      * SWFTagTypes interface
785      */ 
786     public void tagDefineBitsJPEG2( int id, InputStream jpegImage ) throws IOException
787     {
788         println( "jpeg2 id=" + id + " (from input stream)" );        
789     }
790     
791     /**
792      * SWFTagTypes interface
793      */ 
794     public SWFShape tagDefineMorphShape( int id, Rect startBounds, Rect endBounds ) 
795         throws IOException
796     {
797         println( "morph-shape id=" + id + " start: " + 
798                  startBounds + "  end: " + endBounds );
799         return this;
800     }
801     
802     /**
803      * SWFTagTypes interface
804      */ 
805     public void tagDefineBitsLossless( int id, int format, int width, int height,
806                                        Color[] colors, byte[] imageData )
807         throws IOException
808     {
809         dumpBitsLossless( "bits-lossless", id, format, width, height, colors, imageData );
810     }
811     
812     /**
813      * SWFTagTypes interface
814      */ 
815     public void tagDefineBitsLossless2( int id, int format, int width, int height,
816                                         Color[] colors, byte[] imageData )
817         throws IOException
818     {
819         dumpBitsLossless( "bits-lossless2", id, format, width, height, colors, imageData );
820     }    
821     
822     public void dumpBitsLossless( String name, int id, int format, 
823                                   int width, int height,
824                                   Color[] colors, byte[] imageData )
825         throws IOException
826     {
827         int size = 0;
828         if     ( format == SWFConstants.BITMAP_FORMAT_8_BIT  ) size = 8;
829         else if( format == SWFConstants.BITMAP_FORMAT_16_BIT ) size = 16;
830         else if( format == SWFConstants.BITMAP_FORMAT_32_BIT ) size = 32;
831         
832         println( name + " id=" + id + " bits=" + size + 
833                  " width=" + width + " height=" + height );
834         
835         if( dumpHex )
836         {
837             for( int i = 0; i < colors.length; i++ )
838             {
839                 println( "    " + i + ": " + colors[i] );
840             }
841             
842             Hex.dump( writer, imageData, 0L, indent + "    ", false );
843             println( dashes );
844         }
845     }
846     
847     /**
848      * SWFVectors interface
849      * SWFText interface
850      */     
851     public void done() throws IOException
852     {
853         println( "    " + dashes );
854     }
855     
856     /**
857      * SWFVectors interface
858      */     
859     public void line( int dx, int dy ) throws IOException
860     {
861         println( "    line  " + dx + "," + dy );        
862     }
863     
864     /**
865      * SWFVectors interface
866      */     
867     public void curve( int cx, int cy, int dx, int dy ) throws IOException
868     {
869         println( "    curve " + cx + "," + cy + " - " + dx + "," + dy );                
870     }
871     
872     /**
873      * SWFVectors interface
874      */     
875     public void move( int x, int y ) throws IOException
876     {
877         println( "    move  " + x + "," + y );        
878     }
879     
880     /**
881      * SWFShape interface
882      */     
883     public void setFillStyle0( int styleIndex ) throws IOException
884     {
885         println( "    fill0 = " + styleIndex );
886     }
887     
888     /**
889      * SWFShape interface
890      */     
891     public void setFillStyle1( int styleIndex ) throws IOException
892     {
893         println( "    fill1 = " + styleIndex );
894     }    
895     
896     /**
897      * SWFShape interface
898      */     
899     public void setLineStyle( int styleIndex ) throws IOException
900     {
901         println( "    line  = " + styleIndex );
902     }    
903 
904     /**
905      * SWFShape interface
906      */     
907     public void defineFillStyle( Color color ) throws IOException
908     {
909         println( "    fill " + color );
910     }    
911 
912     /**
913      * SWFShape interface
914      */     
915     public void defineFillStyle( Matrix matrix, int[] ratios,
916                                  Color[] colors, boolean radial )
917         throws IOException
918     {
919         println( "    fill radial=" + radial + "  " + matrix );
920         
921         for( int i = 0; i < ratios.length && i < colors.length; i++ )
922         {
923             if( colors[i] == null ) continue;
924             println( "         ratio=" + ratios[i] + " " + colors[i] );
925         }
926     }    
927 
928     /**
929      * SWFShape interface
930      */     
931     public void defineFillStyle( int bitmapId, Matrix matrix, boolean clipped )
932         throws IOException
933     {
934         println( "    fill clipped=" + clipped + " image=" + bitmapId + " " + matrix );
935     }
936     
937     /**
938      * SWFShape interface
939      */     
940     public void defineLineStyle( int width, Color color ) throws IOException
941     {
942         println( "    line-style width=" + width + "  " + color );
943     }
944     
945     /**
946      * SWFText interface
947      */     
948     public void font( int fontId, int textHeight ) throws IOException
949     {
950         println( "    font id=" + fontId + " size=" + textHeight );
951     }
952     
953     /**
954      * SWFText interface
955      */     
956     public void color( Color color ) throws IOException
957     {
958         println( "    color " + color );
959     }
960     
961     /**
962      * SWFText interface
963      */     
964     public void setX( int x ) throws IOException
965     {
966         println( "    x = " + x );
967     }
968 
969     /**
970      * SWFText interface
971      */     
972     public void setY( int y ) throws IOException
973     {
974         println( "    y = " + y );
975     }
976     
977     /**
978      * SWFText interface
979      */     
980     public void text( int[] glyphIndices, int[] glyphAdvances ) throws IOException
981     {
982         StringBuffer buff1 = new StringBuffer();
983         StringBuffer buff2 = new StringBuffer();
984         
985         buff1.append( "(" );
986         buff2.append( "(" );
987         
988         for( int i = 0; i < glyphIndices.length && i < glyphAdvances.length; i++ )
989         {
990             buff1.append( " " );
991             buff2.append( " " );
992             
993             buff1.append( glyphIndices[i] );
994             buff2.append( glyphAdvances[i] );
995         }
996         
997         buff1.append( " )" );
998         buff2.append( " )" );
999 
1000        println( "    text" );
1001        println( "        glyph indices = " + buff1 );
1002        println( "        advances      = " + buff2 );
1003    }
1004    
1005    public void flush() throws IOException
1006    {
1007        writer.flush();
1008    }
1009    
1010    /**
1011     * args[0] = name of SWF file to dump to System.out
1012     * args[1] = if exists then dump-hex is true (dumps binary as hex - otherwise skips)
1013     * args[2] = if exists then decompiles action codes
1014     */
1015    public static void main( String[] args ) throws IOException
1016    {
1017        SWFTagDumper dumper = new SWFTagDumper( args.length > 1, args.length > 2 );
1018        
1019        FileInputStream in  = new FileInputStream( args[0] );
1020        SWFTags tagparser = new TagParser( dumper );
1021        SWFReader reader = new SWFReader( tagparser, in );
1022        
1023        try
1024        {
1025            reader.readFile();
1026        }
1027        finally
1028        {        
1029            dumper.flush();
1030            in.close();
1031        }        
1032    }
1033}