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

Quick Search    Search Deep

Source code: com/anotherbigidea/flash/readers/SWFReader.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.readers;
35  
36  import java.io.*;
37  import com.anotherbigidea.io.*;
38  import com.anotherbigidea.flash.structs.Rect;
39  import com.anotherbigidea.flash.*;
40  import com.anotherbigidea.flash.interfaces.*;
41  import com.anotherbigidea.flash.writers.SWFWriter;
42  
43  /**
44   * Reads a SWF input stream and drives the SWFTags interface.
45   * 
46   * Automatically decompresses the file if necessary.
47   */
48  public class SWFReader
49  {
50      protected SWFTags     mConsumer;
51      protected InStream    mIn;
52      protected InputStream mInputstream;
53      protected boolean     mCompressed;
54      protected String      mFilename;
55      
56    /**
57     * Read from a file.
58     * Must call readFile() in order to properly close the file.
59     * 
60     * @param consumer may also implement the SWFFileSignature interface.
61     */
62    public SWFReader( SWFTags consumer, String filename ) throws IOException {
63      this( consumer, new FileInputStream( filename ) );
64      mFilename = filename;
65    }
66      
67      /**
68       * @param consumer may also implement the SWFFileSignature interface.
69       */
70      public SWFReader( SWFTags consumer, InputStream inputstream )
71      {
72          mConsumer    = consumer;
73          mInputstream = inputstream;
74          mIn          = new InStream( inputstream );
75      }
76  
77    /**
78     * @param consumer may also implement the SWFFileSignature interface.
79     */
80      public SWFReader( SWFTags consumer, InStream instream )
81      {
82          mConsumer = consumer;
83          mIn       = instream;
84      }    
85      
86      /**
87       * Drive the consumer by reading a SWF File - including the header and all tags
88       */
89      public void readFile() throws IOException
90      {
91          readHeader();
92          readTags();
93      if( mFilename != null ) mInputstream.close();
94      }
95      
96      /**
97       * Drive the consumer by reading SWF tags only.  The full header must have
98       * been read prior to this.
99       */
100     public void readTags() throws IOException 
101     {
102         while( readOneTag() != SWFConstants.TAG_END );
103     }
104     
105     /**
106      * Drive the consumer by reading one tag
107      * @return the tag type
108      */
109     public int readOneTag() throws IOException 
110     {
111         int header = mIn.readUI16();
112         
113         int  type   = header >> 6;    //only want the top 10 bits
114         int  length = header & 0x3F;  //only want the bottom 6 bits
115         boolean longTag = (length == 0x3F);
116         
117         if( longTag )
118         {
119             length = (int)mIn.readUI32();
120         }
121         
122         byte[] contents = mIn.read( length );
123         
124         mConsumer.tag( type, longTag, contents );
125         
126         return type;
127     }
128     
129     /**
130      * Read and verify just the file signature.
131      */
132     public void readSignature() throws IOException {
133     int[] sig = { mIn.readUI8(), mIn.readUI8(), mIn.readUI8() };
134       
135     //--Verify File Signature
136     if( ( sig[0] != 0x46 && sig[0] != 0x43 ) || // "F" or "C"
137       ( sig[1] != 0x57 ) ||  // "W"
138       ( sig[2] != 0x53 ) )   // "S"
139     {
140       throw new IOException( "Invalid SWF File Signature" );
141     }
142 
143     mCompressed = sig[0] == 0x43;
144     
145     if( mConsumer instanceof SWFFileSignature ) {
146       ((SWFFileSignature) mConsumer).signature( 
147         mCompressed ?
148           SWFFileSignature.SIGNATURE_COMPRESSED :
149           SWFFileSignature.SIGNATURE_NORMAL );    
150     }
151     }
152     
153     /** 
154      * Read the SWF file header - including the signature.
155      */
156     public void readHeader() throws IOException {
157       readSignature();
158       readRemainderOfHeader();
159     }
160     
161     /**
162      * Read the header after the signature.  The signature must have been read
163      * prior to this.
164      */
165     public void readRemainderOfHeader() throws IOException {
166 
167         int  version   = mIn.readUI8();
168         long length    = mIn.readUI32();
169         
170         //may be compressed from this point onwards
171         if( mCompressed ) mIn.readCompressed();
172         
173         Rect frameSize = new Rect( mIn );
174         int frameRate  = mIn.readUI16() >> 8;
175         int frameCount = mIn.readUI16();                
176         
177         mConsumer.header( version, length, 
178                           frameSize.getMaxX(), frameSize.getMaxY(), 
179                           frameRate, frameCount );                         
180     }
181     
182     /**
183      * Test: read from args[0] and write to args[1].
184      * 
185      * If args[2] is '+' then output is forced to be compressed, if it is '-'
186      * then output is forced to be uncompressed - otherwise the output is the
187      * same as the input.
188      */
189     public static void main( String[] args ) throws IOException {      
190         SWFWriter writer = new SWFWriter( args[1] );
191         
192         if( args.length > 2 ) {
193           if     ( args[2].equals( "+" )) writer.setCompression( true  );
194           else if( args[2].equals( "-" )) writer.setCompression( false );
195         }        
196         
197         SWFReader reader = new SWFReader( writer, args[0] );
198         reader.readFile();
199     }
200 }