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}